package org.jeecg.modules.demo.lydasystem.util;



import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.util.DateUtils;
import org.jeecg.modules.demo.lydasystem.entity.*;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.annotation.PostConstruct;

import java.util.*;
import java.util.Map;
import java.io.*;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.util.Date;

import org.jeecg.modules.demo.lydasystem.entity.TbData;
import org.jeecg.modules.demo.lydasystem.entity.TbDataInfo;
import org.jeecg.modules.demo.lydasystem.service.ITbContentStandardService;
import org.jeecg.modules.demo.lydasystem.service.ITbDataAcquisitionService;
import org.jeecg.modules.demo.lydasystem.service.ITbDataInfoService;
import org.jeecg.modules.demo.lydasystem.service.ITbDataService;
import org.jeecg.modules.system.entity.SysDict;
import org.jeecg.modules.system.entity.SysDictItem;
import org.jeecg.modules.system.service.ISysDictItemService;
import org.jeecg.modules.system.service.ISysDictService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

/**
 * HJ/T212-2005协议TCP服务器
 * 用于接收力控公司水质检测设备数据
 */
@Component
@Configuration
@Async
@Slf4j
public class HJ212DataReceiver {
    private static final int DEFAULT_PORT = 3110; // 默认监听端口
    private ServerSocket serverSocket;
    /**
     * -- GETTER --
     *  检查服务器是否在运行
     */
    @Getter
    private boolean running = false;

    public static final long CONNECTION_TIMEOUT_MS = 60000; // 1分钟超时
    public static final long CONNECTION_CHECK_INTERVAL_MS = 60000; // 1分钟检查间隔

    private ExecutorService threadPool;
    private Timer timeoutTimer;
//    private boolean hasDeviceConnected = false;
    private long serverStartTime;

    private boolean isMonitoring = false; // 监控状态

    private Timer monitoringTimer;
    private AtomicBoolean hasDeviceConnected; // 使用原子布尔类型保证线程安全
    private HJ2122017Config config;
    private final AtomicInteger activeConnections = new AtomicInteger(0);
    private final AtomicInteger connectionCheckCount = new AtomicInteger(0);


    // 告警接口
    public interface AlarmNotifier {
        void sendAlarm(String alarmMessage);
    }

    /**
     * -- SETTER --
     *  设置告警通知器
     * -- SETTER --
     *  设置告警通知器
     * -- SETTER --
     *  设置告警通知器
     * -- SETTER --
     *  设置告警通知器
     * -- SETTER --
     *  设置告警通知器




     */
    @Setter
    private AlarmNotifier alarmNotifier;
    public static HJ212DataReceiver hj212DataReceiver;

    @Autowired
    public  HJ212DataReceiver(){
        hj212DataReceiver = this;
    }

    @PostConstruct
    public void init(){

        hj212DataReceiver = this;

 //       HJ212DataReceiver receiver = new HJ212DataReceiver();
//        receiver.start(DEFAULT_PORT);
    }

    public static void main(String[] args) {
        HJ212DataReceiver receiver = new HJ212DataReceiver();


        // 设置告警通知器（可以根据需要实现不同的告警方式）
        receiver.setAlarmNotifier(new AlarmNotifier() {
            @Override
            public void sendAlarm(String alarmMessage) {
                // 示例：控制台告警
                System.err.println("🚨 系统告警: " + alarmMessage);

                // 这里可以扩展其他告警方式，比如：
                // - 发送邮件
                // - 发送短信
                // - 调用监控系统API
                // - 写入系统日志
                // - 触发声光报警
            }
        });

        receiver.start(DEFAULT_PORT);
    }

    public void start(int port) {
        // 确保在启动前重置所有状态
        resetServerState();

        try {
            config = new HJ2122017Config();
            threadPool = Executors.newFixedThreadPool(10);
            serverSocket = new ServerSocket(port);
            running = true;
            serverStartTime = System.currentTimeMillis();

            System.out.println("HJ212-2017数据接收服务器启动成功，端口: " + port);
            System.out.println("等待水质检测设备连接...");
            System.out.println("连接状态监控间隔: " + (CONNECTION_CHECK_INTERVAL_MS / 1000) + "秒");

            // 立即启动连接监控
            startContinuousConnectionMonitor();

            // 启动服务器状态监控定时器
            startServerStatusMonitor();

            // 主服务器循环
            serverMainLoop();

        } catch (IOException e) {
            System.err.println("服务器启动失败: " + e.getMessage());
            sendAlarm("服务器启动失败: " + e.getMessage());
        } finally {
            stop();
        }
    }

    /**
     * 重置服务器状态
     */
    private void resetServerState() {
        activeConnections.set(0);
        connectionCheckCount.set(0);
        isMonitoring = false;
        serverStartTime = 0;
    }

    /**
     * 服务器主循环
     */
    private void serverMainLoop() {
        while (running) {
            try {
                Socket clientSocket = serverSocket.accept();

                // 增加活跃连接数
                int currentConnections = activeConnections.incrementAndGet();
                String clientInfo = clientSocket.getInetAddress() + ":" + clientSocket.getPort();

                System.out.println("设备连接建立: " + clientInfo +
                        " | 活跃连接数: " + currentConnections +
                        " | 运行时间: " + (System.currentTimeMillis() - serverStartTime) + "ms");

                // 如果有设备连接，重置检查计数器（可选）
                if (currentConnections == 1) {
                    connectionCheckCount.set(0);
                    System.out.println("✅ 检测到设备连接，重置监控检查计数器");
                }

                // 为每个设备连接创建单独的处理线程
                threadPool.execute(new ClientHandler(clientSocket, config, this));

            } catch (SocketException e) {
                // 服务器socket被关闭，正常退出
                if (running) {
                    System.err.println("服务器Socket异常: " + e.getMessage());
                }
            } catch (IOException e) {
                System.err.println("接受客户端连接异常: " + e.getMessage());
                sendAlarm("接受客户端连接异常: " + e.getMessage());
            }
        }
    }

    /**
     * 启动持续连接监控
     */
    private void startContinuousConnectionMonitor() {
        if (isMonitoring) {
            System.out.println("连接监控已在运行中");
            return;
        }

        monitoringTimer = new Timer("ContinuousConnectionMonitor", true);

        // 立即执行第一次检查，然后每隔1分钟检查一次
        monitoringTimer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                performConnectionCheck();
            }
        }, 0, CONNECTION_CHECK_INTERVAL_MS);

        isMonitoring = true;
        System.out.println("持续连接监控已启动，每 " + (CONNECTION_CHECK_INTERVAL_MS / 1000) + " 秒检查一次设备连接状态");
    }

    /**
     * 执行连接检查（线程安全）
     */
    private void performConnectionCheck() {
        if (!running) {
            return;
        }

        try {
            int currentConnections = activeConnections.get();

            if (currentConnections == 0) {
                // 没有活跃连接，发送告警
                int checkCount = connectionCheckCount.incrementAndGet();
                long elapsedMinutes = (System.currentTimeMillis() - serverStartTime) / 60000;

                String alarmMessage = String.format(
                        "持续监控告警 (%d): 服务器运行 %d 分钟，当前无活跃设备连接。\n" +
                                "连接历史: 总检查=%d次, 无连接=%d次\n" +
                                "可能的问题排查:\n" +
                                "1、设备电源状态检查\n" +
                                "2、设备网络连接测试\n" +
                                "3、设备IP地址和端口配置验证\n" +
                                "4、网络防火墙规则检查\n" +
                                "5、设备HJ212-2017协议配置确认\n" +
                                "6、物理线路连接状态",
                        checkCount, elapsedMinutes, checkCount, checkCount
                );

                sendAlarm(alarmMessage);

                // 记录到监控日志
                System.out.println("连接状态检查 [" + checkCount + "]: 无设备连接 (" + elapsedMinutes + "分钟)");
            } else {
                // 有活跃连接，正常状态
                System.out.println("连接状态检查: " + currentConnections + "个活跃连接");
            }
        } catch (Exception e) {
            System.err.println("连接检查异常: " + e.getMessage());
        }
    }

    /**
     * 重启连接监控（当设备断开后调用）
     */
    public synchronized void restartConnectionMonitor() {
        System.out.println("设备连接断开，重新启动连接监控");
        stopConnectionMonitor();
        startContinuousConnectionMonitor();
    }

    /**
     * 停止连接监控
     */
    private synchronized void stopConnectionMonitor() {
        if (monitoringTimer != null) {
            monitoringTimer.cancel();
            monitoringTimer = null;
            isMonitoring = false;
            System.out.println("设备连接监控已停止");
        }
    }

    /**
     * 启动服务器状态监控
     */
    private void startServerStatusMonitor() {
        Timer statusTimer = new Timer("ServerStatusMonitor", true);
        statusTimer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                if (running) {
                    try {
                        long uptime = (System.currentTimeMillis() - serverStartTime) / 1000;
                        String status = String.format(
                                "服务器运行状态: 运行时间=%d秒, 活跃连接=%d, 监控检查=%d次, 监控状态=%s",
                                uptime, activeConnections.get(), connectionCheckCount.get(),
                                isMonitoring ? "运行中" : "已停止"
                        );
                        System.out.println("📊 " + status);
                    } catch (Exception e) {
                        System.err.println("状态监控异常: " + e.getMessage());
                    }
                }
            }
        }, (int)HJ212DataReceiver.CONNECTION_TIMEOUT_MS, (int)HJ212DataReceiver.CONNECTION_CHECK_INTERVAL_MS); // CONNECTION_TIMEOUT_MS秒后开始，每CONNECTION_CHECK_INTERVAL_MS秒报告一次状态
    }

    /**
     * 发送告警信息
     */
    public void sendAlarm(String alarmMessage) {
        if (alarmNotifier != null) {
            try {
                alarmNotifier.sendAlarm(alarmMessage);
            } catch (Exception e) {
                System.err.println("发送告警异常: " + e.getMessage());
            }
        } else {
            System.err.println("🚨 [告警] " + alarmMessage);
        }
    }

    /**
     * 减少活跃连接数（当设备断开时调用）
     */
    public void decrementActiveConnections() {
        try {
            int remaining = activeConnections.decrementAndGet();
            if (remaining < 0) {
                activeConnections.set(0); // 确保不会出现负数
                remaining = 0;
            }
            System.out.println("设备连接减少，剩余活跃连接: " + remaining);

            // 如果连接数为0，确保监控在运行
            if (remaining == 0 && !isMonitoring) {
                restartConnectionMonitor();
            }
        } catch (Exception e) {
            System.err.println("减少连接数异常: " + e.getMessage());
        }
    }

    /**
     * 获取活跃连接数
     */
    public int getActiveConnections() {
        try {
            return activeConnections.get();
        } catch (Exception e) {
            System.err.println("获取活跃连接数异常: " + e.getMessage());
            return 0;
        }
    }

    /**
     * 安全停止服务器
     */
    public void stop() {
        running = false;
        try {
            stopConnectionMonitor();

            if (serverSocket != null && !serverSocket.isClosed()) {
                serverSocket.close();
            }

            if (threadPool != null) {
                threadPool.shutdown();
                if (!threadPool.awaitTermination(5, TimeUnit.SECONDS)) {
                    threadPool.shutdownNow();
                }
            }
        } catch (IOException e) {
            System.err.println("关闭服务器Socket异常: " + e.getMessage());
        } catch (InterruptedException e) {
            threadPool.shutdownNow();
            Thread.currentThread().interrupt();
        } catch (Exception e) {
            System.err.println("停止服务器异常: " + e.getMessage());
        } finally {
            System.out.println("服务器已停止");
        }
    }

    /**
     * 获取服务器运行状态信息
     */
    public String getServerStatus() {
        try {
            return String.format(
                    "服务器状态: %s, 运行时间: %d秒, 活跃连接: %d, 监控检查: %d次",
                    running ? "运行中" : "已停止",
                    (System.currentTimeMillis() - serverStartTime) / 1000,
                    activeConnections.get(),
                    connectionCheckCount.get()
            );
        } catch (Exception e) {
            return "服务器状态获取异常: " + e.getMessage();
        }
    }

}

/**
 * 设备连接处理线程
 */
@Component
@Configuration
@Async
class ClientHandler implements Runnable{
    private Socket socket;
    private BufferedReader reader;
    private PrintWriter writer;
    private HJ2122017Parser parser;
    private HJ2122017Config config = new HJ2122017Config();
    private TbDataAcquisition tbDataAcquisition;

    private String clientId;
    private HJ212DataReceiver server;

    @Autowired
    private ITbDataAcquisitionService tbDataAcquisitionService;

    @Autowired
    private ITbDataService tbDataService;

    @Autowired
    private ITbDataInfoService tbDataInfoService;

    @Autowired
    private ISysDictService iSysDictService;

    @Autowired
    private ISysDictItemService iSysDictItemService;

    @Autowired
    private ITbContentStandardService iTbContentStandardService;

    public static ClientHandler clientHandler = new ClientHandler();

    private boolean connectionActive = true;

    @Autowired
    public ClientHandler(){
        clientHandler = this;
        System.out.println("clientHandler加载完毕！");

    }

    public ClientHandler(Socket socket) {
        this.socket = socket;
        this.parser = new HJ2122017Parser();
    }

    public ClientHandler(Socket socket, HJ2122017Config config, HJ212DataReceiver server) {
        this.socket = socket;
        this.server = server;
        this.parser = new HJ2122017Parser();
        this.clientId = socket.getInetAddress().getHostAddress() + ":" + socket.getPort();

        System.out.println("创建设备处理线程: " + clientId);
    }

    @PostConstruct
    public void init(){

        clientHandler = this;
    }

//    @Override
//    public void run() {
//        try {
//            // 初始化输入输出流
//            reader = new BufferedReader(new InputStreamReader(
//                    socket.getInputStream(), StandardCharsets.UTF_8));
//            writer = new PrintWriter(new OutputStreamWriter(
//                    socket.getOutputStream(), StandardCharsets.UTF_8), true);
//
//            System.out.println("开始处理设备数据: " + socket.getInetAddress());
//
//            String message;
//            while ((message = readMessage()) != null) {
//                System.out.println("收到原始数据: " + message);
//
//                // 解析HJ212协议数据
//                List<Map<String, Object>> parsedMessages = HJ212MultiParser.parseMultiHJ212(message);
//
//                for (int i = 0; i < parsedMessages.size(); i++) {
//                    if (parsedMessages.get(i).get("cn").toString().contains("20")) {
//                        saveMessage(parsedMessages.get(i), i + 1);
//                    }
//                }
//            }
//
//        } catch (IOException e) {
//            System.err.println("设备连接异常: " + e.getMessage());
//        } finally {
//            closeConnection();
//        }
//    }

    @Override
    public void run() {

        try {
            initializeStreams();
            processDeviceCommunication();
        } catch (IOException e) {
            System.err.println("设备通信异常 [" + clientId + "]: " + e.getMessage());
            server.sendAlarm("设备通信异常: " + clientId + " - " + e.getMessage());
        } catch (ParseException e) {
            throw new RuntimeException(e);
        } finally {
            closeConnection();
        }

//        try {
//            // 初始化输入输出流
//            reader = new BufferedReader(new InputStreamReader(
//                    socket.getInputStream(), StandardCharsets.UTF_8));
//            writer = new PrintWriter(new OutputStreamWriter(
//                    socket.getOutputStream(), StandardCharsets.UTF_8), true);
//
//            System.out.println("开始处理设备数据: " + socket.getInetAddress());
//
//            String message;
//            while ((message = readMessage()) != null) {
//                System.out.println("收到原始数据: " + message);
//
//            }
//
//        } catch (IOException e) {
//            System.err.println("设备连接异常: " + e.getMessage());
//        } finally {
//            closeConnection();
//        }
    }


    // 其他方法保持不变...
    private void initializeStreams() throws IOException {
        reader = new BufferedReader(new InputStreamReader(
                socket.getInputStream(), StandardCharsets.UTF_8));
        writer = new PrintWriter(new OutputStreamWriter(
                socket.getOutputStream(), StandardCharsets.UTF_8), true);

        System.out.println("设备流初始化完成: " + clientId);
    }

    private void processDeviceCommunication() throws IOException, ParseException {
        String message;
        long lastDataTime = System.currentTimeMillis();

        while (connectionActive && (message = readHJ212Message()) != null) {
            lastDataTime = System.currentTimeMillis();
            System.out.println("收到设备数据 [" + clientId + "]: " + message);

            if (!message.contains("QnRtn=")) {
                // 解析协议数据
                HJ2122017Data data = parser.parse(message);
                if (data != null) {
                    if (authenticateDevice(data)) {
                        processValidData(data);
                        sendAcknowledgement(data, true);
                    } else {
                        System.err.println("设备认证失败: " + data.getDeviceCode());
                        server.sendAlarm("设备认证失败: " + data.getDeviceCode());
                        sendAcknowledgement(data, false);
                    }
                } else {
                    System.err.println("数据解析失败");
                    sendNegativeAcknowledgement();
                }
            }

            // 检查连接是否超时（5分钟无数据）
            if (System.currentTimeMillis() - lastDataTime > 300000) {
                System.out.println("设备数据接收超时: " + clientId);
                connectionActive = false;
                break;
            }

            // 解析HJ212协议数据
            List<Map<String, Object>> parsedMessages = HJ212MultiParser.parseMultiHJ212(message);

            for (int i = 0; i < parsedMessages.size(); i++) {
                if (parsedMessages.get(i).get("CN").toString().contains("20")) {
                    saveMessage(parsedMessages.get(i), i + 1);
                }
            }
         }
    }

    private String readHJ212Message() throws IOException {
        // 设置读取超时
        socket.setSoTimeout((int) HJ212DataReceiver.CONNECTION_TIMEOUT_MS); // 30秒读取超时

        StringBuilder buffer = new StringBuilder();
        char[] charBuffer = new char[1024];
        int bytesRead;

        try {
            while ((bytesRead = reader.read(charBuffer)) != -1) {
                buffer.append(charBuffer, 0, bytesRead);
                String content = buffer.toString();

                if (content.startsWith("##") && content.endsWith("\r\n")) {
                    if (validateMessageLength(content)) {
                        return content;
                    }
                }

                if (buffer.length() > 8192) {
                    System.err.println("消息过长: " + clientId);
                    return null;
                }
            }
        } catch (SocketTimeoutException e) {
            // 读取超时是正常的，返回null让外层处理
            return null;
        } catch (IOException e) {
            connectionActive = false;
            throw e;
        }

        return null;
    }

    private boolean validateMessageLength(String message) {
        try {
            if (message.length() < 10)
                return false;
            return true;
      //      String lengthStr = message.substring(2, 6);
      //      int declaredLength = Integer.parseInt(lengthStr);
     //       int actualLength = message.length() - 10;
     //       return declaredLength == actualLength;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    private boolean authenticateDevice(HJ2122017Data data) {
        return config.isDeviceAllowed(data.getDeviceCode()) &&
                config.validatePassword(data.getDeviceCode(), data.getPassword());
    }

    private void processValidData(HJ2122017Data data) {
        System.out.println("=== 水质数据解析结果 [" + clientId + "] ===");
        System.out.println("设备编码(MN): " + data.getDeviceCode());
        System.out.println("数据时间: " + data.getDataTime());

        data.getPollutants().forEach((factor, value) -> {
            System.out.println("监测因子 " + factor + ": " + value + " " +
                    data.getPollutantUnit(factor));
        });

//        saveToDatabase(data);
        if (data.isRealTimeData()) {
            sendToMonitoringPlatform(data);
        }
    }

    private void sendAcknowledgement(HJ2122017Data data, boolean success) {
        try {
            String ackMessage = success ?
                    parser.buildAckMessage(data) : parser.buildNackMessage(data);
            writer.write(ackMessage);
            writer.flush();
            System.out.println("发送应答 [" + (success ? "ACK" : "NAK") + "]: " + ackMessage);
        } catch (Exception e) {
            System.err.println("发送应答异常: " + e.getMessage());
        }
    }

    private void sendNegativeAcknowledgement() {
        try {
            writer.write("##0000NAK\r\n");
            writer.flush();
        } catch (Exception e) {
            System.err.println("发送否定应答异常: " + e.getMessage());
        }
    }

//    private void saveToDatabase(HJ2122017Data data) {
//        try {
//            System.out.println("数据保存到数据库: " + data.getDeviceCode());
//        } catch (Exception e) {
//            System.err.println("数据库存储失败: " + e.getMessage());
//            server.sendAlarm("数据存储失败: " + e.getMessage());
//        }
//    }


    private void closeConnection() {
        connectionActive = false;

        try {
            if (reader != null) {
                reader.close();
            }
            if (writer != null) {
                writer.close();
            }
            if (socket != null && !socket.isClosed()) {
                socket.close();
            }

            // 安全减少活跃连接数
            if (server != null) {
                server.decrementActiveConnections();
            }

            System.out.println("设备连接关闭: " + clientId);
            safeSendAlarm("设备连接断开: " + clientId + " | 剩余连接: " +
                    (server != null ? server.getActiveConnections() : "未知"));

        } catch (IOException e) {
            System.err.println("关闭连接异常: " + e.getMessage());
        } catch (Exception e) {
            System.err.println("关闭连接过程中发生异常: " + e.getMessage());
        }
    }


    //数据存储
    private void saveMessage(Map<String, Object> message, int index) throws ParseException {

        TbData tbData = new TbData();
        System.out.println("第 " + index + " 条消息:");
        System.out.println("  长度字段: " + message.get("Length"));
        System.out.println("  CRC校验: " + message.get("CRC"));
        System.out.println("  系统类型(ST): " + message.get("ST"));
        System.out.println("  命令编号(CN): " + message.get("CN"));
        System.out.println("  设备标识(MN): " + message.get("MN"));

        if (message.containsKey("QN")) {
            System.out.println("  时间戳(QN): " + message.get("QN"));
        }

        if (message.containsKey("CP")) {
            @SuppressWarnings("unchecked")
            Map<String, Object> cpData = (Map<String, Object>) message.get("CP");
            System.out.println("  数据时间: " + cpData.get("DataTime"));

            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
            tbData.setDatetime(sdf.parse(cpData.get("DataTime").toString()));

            // 显示所有测量项
            for (Map.Entry<String, Object> entry : cpData.entrySet()) {
                if (entry.getValue() instanceof Map) {
                    @SuppressWarnings("unchecked")
                    Map<String, String> measurement = (Map<String, String>) entry.getValue();
                    System.out.println("  测量项 " + entry.getKey() + ": " + measurement);
                }
            }
        }


        if (message.get("CN") != null){
            tbData.setCn(message.get("CN").toString());
        }
         if (message.get("MN") != null){
             tbData.setMn(message.get("MN").toString());
        }
        if (message.get("CP") != null){
            tbData.setCp(message.get("CP").toString());
        }
        if (message.get("PW") != null){
            tbData.setPw(message.get("PW").toString());
        }
        if (message.get("ST") != null){
            tbData.setSt(message.get("ST").toString());
        }
        if (message.get("QN") != null){
            tbData.setQn(message.get("QN").toString());
        }

        List<TbDataInfo> tbDataInfoList = new ArrayList<>();
        Map<String, Object> cpData = (Map<String, Object>) message.get("CP");
        Date diDate = new Date();


        SysDict sysDict = new SysDict();
        sysDict.setDictCode("cn_code");
        QueryWrapper<SysDict> sysDictQueryWrapper = new QueryWrapper<SysDict>(sysDict);
        SysDict sysDict2 = clientHandler.iSysDictService.getOne(sysDictQueryWrapper);
        Map<String,String> sysDictMap = new HashMap<String,String>();

//        SysDictItem sysDictItem = new SysDictItem();
//        sysDictItem.setDictId(sysDict2.getId());
//        QueryWrapper<SysDictItem> sysDictItemQueryWrapper = new QueryWrapper<SysDictItem>(sysDictItem);
//        List<SysDictItem> sysDictItemList = clientHandler.iSysDictItemService.list(sysDictItemQueryWrapper);
//        for (SysDictItem entry3 : sysDictItemList){
//            sysDictMap.put(entry3.getItemValue(),entry3.getItemText());
//        }

        List<TbContentStandard> contentStandardList = new ArrayList<>();
        contentStandardList = clientHandler.iTbContentStandardService.list();
        Map<String,TbContentStandard> standardMap = new HashMap<>();
        for (TbContentStandard tbContentStandard : contentStandardList) {
            String key = tbContentStandard.getAcquisitionName();
            standardMap.put(key, tbContentStandard);
        }

        List<TbDataAcquisition> tbDataAcquisitionArrayList = new ArrayList<>();

        for (Map.Entry<String, Object> entry : cpData.entrySet()) {

            TbDataInfo tbDataInfo = new TbDataInfo();
            tbDataInfo.setDataId(tbData.getId());
            if (entry.getValue() instanceof Map) {
                @SuppressWarnings("unchecked")
                Map<String, String> measurement = (Map<String, String>) entry.getValue();

                for (Map.Entry<String, String> entry2 : measurement.entrySet()) {
                    tbDataInfo.setCpCode(entry2.getKey().split("-")[0]);
                    break;
                }

                tbDataInfo.setCpCnname(tbDataInfo.getCpCode());

                for (Map.Entry<String, String> entry2 : measurement.entrySet()){

                    if (entry2.getKey().contains("Rtd"))
                        tbDataInfo.setRtd(entry2.getValue());
                    else if (entry2.getKey().contains("Avg"))
                        tbDataInfo.setAvg(entry2.getValue());
                    else if (entry2.getKey().contains("Flag"))
                        tbDataInfo.setFlag(entry2.getValue());
                    else if (entry2.getKey().contains("Max"))
                        tbDataInfo.setMax(entry2.getValue());
                    else if (entry2.getKey().contains("Min"))
                        tbDataInfo.setMin(entry2.getValue());
                    else if (entry2.getKey().contains("Cou"))
                        tbDataInfo.setCou(entry2.getValue());


                }
                if (message.get("CN").toString().equals("2061")) {//用于现场机上报污染物小时历史数据

                    tbDataAcquisition = new TbDataAcquisition();

                    tbDataAcquisition.setAcquisitionFrom("10");
                    tbDataAcquisition.setAcquisitionTime(tbDataInfo.getDatetime());
                    tbDataAcquisition.setAcquisitionType("10");
                    tbDataAcquisition.setAcquisitionName(tbDataInfo.getCpCnname());

                    tbDataAcquisition.setAcquisitionValue(tbDataInfo.getAvg());

                    //BigDecimal pf = ll.multiply(hl).multiply(t);//计算瞬时排放量 = 瞬时流量(L/s) * 含量(mg/L) * 0.001
                    //String paifang = pf.setScale(3, RoundingMode.HALF_UP).toString();
                    tbDataAcquisition.setEmissions(tbDataInfo.getCou());
                    tbDataAcquisition.setDeviceCode(tbDataInfo.getCpCode());
                    tbDataAcquisition.setNotes("");
                    tbDataAcquisition.setUnit("10");

                    if (tbDataInfo.getCpCode().contains("e")) {
                        tbDataAcquisition.setUnit("20");

                    } else if (tbDataInfo.getCpCode().equals("w01001")) {
                        tbDataAcquisition.setUnit("30");
//                        DecimalFormat df1 = new DecimalFormat("0.00");
//                        tbDataAcquisition.setAcquisitionValue(df1.format(floatValue_hl));
                        tbDataAcquisition.setEmissions("");
                    } else if (tbDataInfo.getCpCode().equals("w20089") || tbDataInfo.getCpCode().equals("w20111")) {
                        tbDataAcquisition.setUnit("40");
                    }
                    if (tbDataInfo.getCpCode().contains("w") && !tbDataInfo.getCpCode().equals("w01001")) {

                        float bz = Float.parseFloat(standardMap.get(tbDataInfo.getCpCnname()).getStandardVal());
                        //   BigDecimal bz = BigDecimal.valueOf(dValue);
                        if (Float.parseFloat(tbDataInfo.getAvg()) >= bz) {
                            tbDataAcquisition.setExceeding("1");
                        } else {
                            tbDataAcquisition.setExceeding("0");
                        }
                    }
                    tbDataAcquisition.setSysOrgCode("");
                    tbDataAcquisition.setCreateBy("1952916863481241602");
                    tbDataAcquisition.setCreateTime(DateUtils.parseDatetime(DateUtils.now()));
                    tbDataAcquisition.setAcquisitionTime(diDate);
                    tbDataAcquisitionArrayList.add(tbDataAcquisition);
                }

                tbDataInfo.setDatetime(diDate);

                tbDataInfoList.add(tbDataInfo);



            }
            else{
                if (entry.getKey().contains("DataTime")) {
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
                    String dateStr = ((Map<?, ?>) message.get("CP")).get("DataTime").toString();
                    diDate = sdf.parse(dateStr);

                }
            }
        }

        if (!tbDataAcquisitionArrayList.isEmpty()) {
            clientHandler.tbDataAcquisitionService.saveBatch(tbDataAcquisitionArrayList);
        }
        clientHandler.tbDataService.saveMain(tbData,tbDataInfoList);

        System.out.println("------------------------------------------");
    }


    /**
     * 读取完整的HJ212协议消息
     */
    private String readMessage() throws IOException {
        StringBuilder buffer = new StringBuilder();
        char[] charBuffer = new char[1024];
        int bytesRead;

        while ((bytesRead = reader.read(charBuffer)) != -1) {
            buffer.append(charBuffer, 0, bytesRead);
            String content = buffer.toString();

            // HJ212协议以##开头，以\r\n结尾
            if (content.startsWith("##") && content.endsWith("\r\n")) {
                return content;
            }

            // 超时检查（简化处理）
            if (buffer.length() > 8192) { // 防止缓冲区溢出
                System.err.println("消息过长或格式错误");
                return null;
            }
        }
        return null;
    }

    /**
     * 处理解析后的水质数据
     */
    private void processData(HJ2122017Data data) {
        System.out.println("=== 水质数据解析结果 ===");
        System.out.println("系统编号: " + data.getSystemCode());
        System.out.println("命令编号: " + data.getCommandCode());
        System.out.println("设备编号: " + data.getDeviceCode());
        System.out.println("数据时间: " + data.getDataTime());
        System.out.println("污染物数据: " + data.getPollutants());

        // 这里可以添加数据存储、转发等业务逻辑
        saveToDatabase(data);
        sendToMonitoringPlatform(data);
    }

    /**
     * 发送确认应答
     */
    private void sendAck(HJ2122017Data data) {
        String ackMessage = parser.buildAckMessage(data);
        writer.write(ackMessage);
        writer.flush();
        System.out.println("发送应答: " + ackMessage);
    }

    /**
     * 发送否定应答
     */
    private void sendNack() {
        String nackMessage = "##0000NAK\r\n"; // 简化处理
        writer.write(nackMessage);
        writer.flush();
        System.out.println("发送否定应答");
    }

    /**
     * 保存到数据库（示例）
     */
    private void saveToDatabase(HJ2122017Data data) {
        try {
            System.out.println("数据保存到数据库: " + data.getDeviceCode());
        } catch (Exception e) {
            System.err.println("数据库存储失败: " + e.getMessage());
            safeSendAlarm("数据存储失败: " + e.getMessage());
        }
    }

    /**
     * 发送到监控平台（示例）
     */
    private void sendToMonitoringPlatform(HJ2122017Data data) {
        // 实现向上级平台转发数据的逻辑
        System.out.println("数据发送到监控平台: " + data.getDeviceCode());
    }

    /**
     * 安全发送告警（防止空指针）
     */
    private void safeSendAlarm(String alarmMessage) {
        try {
            if (server != null) {
                server.sendAlarm(alarmMessage);
            } else {
                System.err.println("🚨 [告警-无服务器实例] " + alarmMessage);
            }
        } catch (Exception e) {
            System.err.println("发送告警失败: " + e.getMessage());
        }
    }

}


/**
 * HJ/T212-2005协议解析器
 */
class HJ212Parser {
    private static final Pattern MESSAGE_PATTERN =
            Pattern.compile("##(\\d+)(.*)([0-9A-Fa-f]{4})\\r\\n");
    private static final Pattern DATA_PATTERN =
            Pattern.compile("ST=(\\d+);CN=(\\d+);PW=([^;]*);MN=([^;]*);CP=&&(.*)&&");
    private static final SimpleDateFormat DATE_FORMAT =
            new SimpleDateFormat("yyyyMMddHHmmss");

    /**
     * 解析HJ212协议数据
     */
    public HJ2122017Data parse(String message) {
        try {
            Matcher matcher = MESSAGE_PATTERN.matcher(message);
            if (!matcher.matches()) {
                System.err.println("消息格式不匹配");
                return null;
            }

            int length = Integer.parseInt(matcher.group(1));
            String dataContent = matcher.group(2);
            String crc = matcher.group(3);

            // CRC校验（简化处理，实际应实现完整校验）
            if (!verifyCRC(dataContent, crc)) {
                System.err.println("CRC校验失败");
                return null;
            }

            // 解析数据段
            return parseDataContent(dataContent);

        } catch (Exception e) {
            System.err.println("解析异常: " + e.getMessage());
            return null;
        }
    }

    /**
     * 解析数据内容
     */
    private HJ2122017Data parseDataContent(String dataContent) {
        try {
            Matcher matcher = DATA_PATTERN.matcher(dataContent);
            if (!matcher.matches()) {
                System.err.println("数据内容格式错误");
                return null;
            }

            HJ2122017Data data = new HJ2122017Data();
            data.setSystemCode(matcher.group(1)); // ST
            data.setCommandCode(matcher.group(2)); // CN
            data.setPassword(matcher.group(3)); // PW
            data.setDeviceCode(matcher.group(4)); // MN

            String cpContent = matcher.group(5); // CP内容
            parseCPContent(cpContent, data);

            return data;

        } catch (Exception e) {
            System.err.println("解析数据内容异常: " + e.getMessage());
            return null;
        }
    }

    /**
     * 解析CP字段（命令参数）
     */
    private void parseCPContent(String cpContent, HJ2122017Data data) {
        try {
            String[] parts = cpContent.split(";");
            Map<String, String> pollutants = new HashMap<>();

            for (String part : parts) {
                if (part.startsWith("DataTime=")) {
                    data.setDataTime(part.substring(9));
                } else if (part.contains("-Rtd=")) {
                    // 污染物实时数据，如B01-Rtd=36.91
                    String[] keyValue = part.split("=");
                    if (keyValue.length == 2) {
                        pollutants.put(keyValue[0], keyValue[1]);
                    }
                } else if (part.contains("-Flag=")) {
                    // 数据标记，如B01-Flag=N
                    String[] keyValue = part.split("=");
                    if (keyValue.length == 2) {
                        String key = keyValue[0].replace("-Flag", "");
                        pollutants.put(key + "-Flag", keyValue[1]);
                    }
                }
                // 可以扩展解析其他字段
            }

            data.setPollutants(pollutants);

        } catch (Exception e) {
            System.err.println("解析CP内容异常: " + e.getMessage());
        }
    }

    /**
     * CRC校验（需要根据协议附录A实现）
     */
    private boolean verifyCRC(String data, String receivedCRC) {
        // 简化实现，实际应按照协议实现CRC-16校验
        String calculatedCRC = calculateCRC(data);
        return calculatedCRC.equalsIgnoreCase(receivedCRC);
    }

    /**
     * 计算CRC（参考协议附录A）
     */
    private String calculateCRC(String data) {
        try {
            byte[] bytes = data.getBytes(StandardCharsets.US_ASCII);
            int crc = 0xFFFF;

            for (byte b : bytes) {
                crc ^= (b & 0xFF);
                for (int i = 0; i < 8; i++) {
                    if ((crc & 0x0001) != 0) {
                        crc = (crc >> 1) ^ 0xA001;
                    } else {
                        crc = crc >> 1;
                    }
                }
            }

            return String.format("%04X", crc & 0xFFFF);
        } catch (Exception e) {
            System.err.println("CRC计算异常: " + e.getMessage());
            return "0000";
        }
    }

    /**
     * 构建应答消息
     */
    public String buildAckMessage(HJ2122017Data data) {
        String ackData = String.format("ST=%s;CN=9011;PW=%s;MN=%s;CP=&&DataTime=%s&&",
                data.getSystemCode(), data.getPassword(), data.getDeviceCode(),
                new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));

        String crc = calculateCRC(ackData);
        return String.format("##%04d%s%s\r\n", ackData.length(), ackData, crc);
    }
}

/**
 * HJ212协议数据模型
 */
class HJ212Data {
    private String systemCode;      // 系统编码（ST）
    private String commandCode;     // 命令编码（CN）
    private String password;        // 访问密码（PW）
    private String deviceCode;      // 设备编码（MN）
    private String dataTime;        // 数据时间
    private Map<String, String> pollutants; // 污染物数据

    // getter和setter方法
    public String getSystemCode() { return systemCode; }
    public void setSystemCode(String systemCode) { this.systemCode = systemCode; }

    public String getCommandCode() { return commandCode; }
    public void setCommandCode(String commandCode) { this.commandCode = commandCode; }

    public String getPassword() { return password; }
    public void setPassword(String password) { this.password = password; }

    public String getDeviceCode() { return deviceCode; }
    public void setDeviceCode(String deviceCode) { this.deviceCode = deviceCode; }

    public String getDataTime() { return dataTime; }
    public void setDataTime(String dataTime) { this.dataTime = dataTime; }

    public Map<String, String> getPollutants() { return pollutants; }
    public void setPollutants(Map<String, String> pollutants) { this.pollutants = pollutants; }

    @Override
    public String toString() {
        return String.format("HJ212Data{ST=%s, CN=%s, MN=%s, Time=%s, Pollutants=%s}",
                systemCode, commandCode, deviceCode, dataTime, pollutants);
    }
}

/**
 * HJ212-2017协议解析器
 * 参考标准: HJ212-2017代替HJ/T 212-2005[citation:1]
 */
class HJ2122017Parser {
    private static final Pattern MESSAGE_PATTERN =
            Pattern.compile("^##(\\d{4})(.+)([0-9A-Fa-f]{4})\r\n$");
//    private static final Pattern DATA_SECTION_PATTERN =
//            Pattern.compile("QN=([^;]*);ST=([^;]*);CN=([^;]*);PW=([^;]*);MN=([^;]*);Flag=([^;]*);CP=&&(.*)&&");
private static final Pattern MAIN_PATTERN =
        Pattern.compile("ST=([^;]*);CN=([^;]*);PW=([^;]*);MN=([^;]*);Flag=([^;]*);CP=&&(.*)&&");
    private static final Pattern QN_PATTERN =
            Pattern.compile("QN=([^;]*);");
    private static final SimpleDateFormat QN_FORMAT =
            new SimpleDateFormat("yyyyMMddHHmmssSSS");

    /**
     * 解析HJ212-2017协议数据
     */
    public HJ2122017Data parse(String message) {
        try {
            // 基本格式验证
            Matcher matcher = MESSAGE_PATTERN.matcher(message);
            if (!matcher.matches()) {
                System.err.println("消息格式不匹配HJ212-2017协议");
                return null;
            }

            int length = Integer.parseInt(matcher.group(1));
            String dataContent = matcher.group(2);
            String receivedCRC = matcher.group(3);

            // CRC校验
            if (!verifyCRC(dataContent, receivedCRC)) {
                System.err.println("CRC校验失败");
                return null;
            }

            // 解析数据段
            return parseDataSection(dataContent);

        } catch (Exception e) {
            System.err.println("解析异常: " + e.getMessage());
            return null;
        }
    }

    private HJ2122017Data parseDataSection(String dataContent) {

        Map<String, String> result = new HashMap<>();
        HJ2122017Data data = new HJ2122017Data();
        try {


            // 先尝试提取QN（如果存在）
            Matcher qnMatcher = QN_PATTERN.matcher(dataContent);
            if (qnMatcher.find()) {
                result.put("QN", qnMatcher.group(1));
                // 移除QN部分继续解析
                dataContent = dataContent.substring(qnMatcher.end());
            }

            // 解析主要部分
            Matcher mainMatcher = MAIN_PATTERN.matcher(dataContent);
            if (mainMatcher.find()) {
                result.put("ST", mainMatcher.group(1));
                result.put("CN", mainMatcher.group(2));
                result.put("PW", mainMatcher.group(3));
                result.put("MN", mainMatcher.group(4));
                result.put("Flag", mainMatcher.group(5));
                result.put("CP", mainMatcher.group(6));

                data.setRequestTime(result.get("QN")); // QN
                data.setSystemCode(result.get("ST"));  // ST
                data.setCommandCode(result.get("CN")); // CN
                data.setPassword(result.get("PW"));    // PW
                data.setDeviceCode(result.get("MN"));  // MN
                data.setFlag(result.get("Flag"));        // Flag
                String cpContent = result.get("CP");   // CP内容
                parseCPContent(cpContent, data);

                return data;

            } else {
                throw new IllegalArgumentException("数据段格式错误");
            }

        } catch (Exception e) {
            System.err.println("解析数据段异常: " + e.getMessage());
            return null;
        }
    }

    private void parseCPContent(String cpContent, HJ2122017Data data) {
        try {
            Map<String, String> pollutants = new HashMap<>();
            Map<String, String> dataFlags = new HashMap<>();
            Map<String, String> units = new HashMap<>();

            String[] parameters = cpContent.split(";");

            for (String param : parameters) {
                if (param.startsWith("DataTime=")) {
                    data.setDataTime(param.substring(9));
                } else if (param.contains("-")) {
                    // 处理监测因子数据，如w01018-Rtd=12.5,w01018-Flag=N
                    String[] keyValue = param.split("=");
                    if (keyValue.length == 2) {
                        String key = keyValue[0];
                        String value = keyValue[1];

                        if (key.endsWith("-Rtd")) {
                            // 实时数据
                            String factor = key.replace("-Rtd", "");
                            pollutants.put(factor, value);
                        } else if (key.endsWith("-Flag")) {
                            // 数据标记
                            String factor = key.replace("-Flag", "");
                            dataFlags.put(factor, value);
                        } else if (key.endsWith("-Unit")) {
                            // 单位
                            String factor = key.replace("-Unit", "");
                            units.put(factor, value);
                        } else if (key.endsWith("-Avg")) {
                            // 平均值数据
                            String factor = key.replace("-Avg", "");
                            pollutants.put(factor + "_Avg", value);
                        }
                    }
                }
            }

            data.setPollutants(pollutants);
            data.setDataFlags(dataFlags);
            data.setUnits(units);

        } catch (Exception e) {
            System.err.println("解析CP内容异常: " + e.getMessage());
        }
    }

    /**
     * CRC校验（基于HJ212-2017附录A）[citation:2][citation:8]
     */
    private boolean verifyCRC(String data, String receivedCRC) {

        //        String calculatedCRC = calculateCRC(data);
//        boolean valid = calculatedCRC.equalsIgnoreCase(receivedCRC);
//        if (!valid) {
//            System.err.println("CRC不匹配: 计算=" + calculatedCRC + ", 接收=" + receivedCRC);
//        }
        return CRC16Checker.verifyCRC(data, receivedCRC);
    }

    private String calculateCRC(String data) {
        try {
            byte[] bytes = data.getBytes(StandardCharsets.US_ASCII);
            int crc = 0xFFFF;
            int polynomial = 0xA001;

            for (byte b : bytes) {
                crc ^= (b & 0xFF);
                for (int i = 0; i < 8; i++) {
                    if ((crc & 0x0001) != 0) {
                        crc = (crc >> 1) ^ polynomial;
                    } else {
                        crc = crc >> 1;
                    }
                }
            }

            return String.format("%04X", crc & 0xFFFF);
        } catch (Exception e) {
            System.err.println("CRC计算异常: " + e.getMessage());
            return "0000";
        }
    }

    /**
     * 构建确认应答消息（CN=9011）
     */
    public String buildAckMessage(HJ2122017Data data) {
        String qn = QN_FORMAT.format(new Date());
        String ackData = String.format("QN=%s;ST=%s;CN=9011;PW=%s;MN=%s;Flag=4;CP=&&DataTime=%s&&",
                qn, data.getSystemCode(), data.getPassword(), data.getDeviceCode(),
                new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));

        String crc = calculateCRC(ackData);
        return String.format("##%04d%s%s\r\n", ackData.length(), ackData, crc);
    }

    public String buildNackMessage(HJ2122017Data data) {
        String qn = QN_FORMAT.format(new Date());
        String nackData = String.format("QN=%s;ST=%s;CN=9012;PW=%s;MN=%s;Flag=4;CP=&&&&",
                qn, data.getSystemCode(), data.getPassword(), data.getDeviceCode());

        String crc = calculateCRC(nackData);
        return String.format("##%04d%s%s\r\n", nackData.length(), nackData, crc);
    }
}

/**
 * HJ212-2017协议数据模型
 * 对应标准中定义的数据结构[citation:3][citation:8]
 */
@Setter
@Getter
class HJ2122017Data {
    // Getter和Setter方法
    private String requestTime;     // 请求编号 QN=YYYYMMDDHHmmssSSS
    private String systemCode;      // 系统编码 ST
    private String commandCode;     // 命令编码 CN
    private String password;        // 访问密码 PW
    private String deviceCode;      // 设备编码 MN
    private String flag;            // 标志位 Flag
    private String dataTime;        // 数据时间 DataTime
    private String qrtn;
    private Map<String, String> pollutants; // 污染物数据
    private Map<String, String> dataFlags;  // 数据标记
    private Map<String, String> units;      // 单位信息

    // 业务方法
    public String getPollutantUnit(String factor) {
        return units != null ? units.get(factor) : "";
    }

    public boolean isRealTimeData() {
        return "2011".equals(commandCode); // 2011为实时数据命令[citation:3]
    }

    public String getDataFlag(String factor) {
        return dataFlags != null ? dataFlags.get(factor) : "N";
    }

    @Override
    public String toString() {
        return String.format("HJ212Data{QN=%s, ST=%s, CN=%s, MN=%s, Time=%s, Pollutants=%d}",
                requestTime, systemCode, commandCode, deviceCode, dataTime,
                pollutants != null ? pollutants.size() : 0);
    }
}


/**
 * HJ212-2017服务器配置
 */
class HJ2122017Config {
    private Set<String> allowedDevices;
    private Map<String, String> devicePasswords;
    private Properties properties;

    public HJ2122017Config() {
        loadDefaultConfig();
    }

    private void loadDefaultConfig() {
        allowedDevices = new HashSet<>();
        devicePasswords = new HashMap<>();
        properties = new Properties();

        // 服务器配置
        properties.setProperty("server.port", "3110");
        properties.setProperty("server.max.connections", "10");
        properties.setProperty("connection.timeout.ms", "60000");
        properties.setProperty("alarm.enabled", "true");

        // 告警配置
        properties.setProperty("alarm.console.enabled", "true");
        properties.setProperty("alarm.file.enabled", "false");
        properties.setProperty("alarm.file.path", "alarms.log");
        properties.setProperty("alarm.email.enabled", "false");
        properties.setProperty("alarm.email.smtp.host", "smtp.example.com");
        properties.setProperty("alarm.email.smtp.port", "587");
        properties.setProperty("alarm.email.username", "user@example.com");
        properties.setProperty("alarm.email.password", "password");
        properties.setProperty("alarm.email.to", "admin@example.com");

        // 示例设备
        allowedDevices.add("dsj");
        devicePasswords.put("dsj", "dsj123456");
    }

    public boolean isDeviceAllowed(String deviceCode) {
        return allowedDevices.contains(deviceCode);
    }

    public boolean validatePassword(String deviceCode, String password) {
        String expectedPwd = devicePasswords.get(deviceCode);
        return expectedPwd != null && expectedPwd.equals(password);
    }

    public int getServerPort() {
        return Integer.parseInt(properties.getProperty("server.port"));
    }

    public int getMaxConnections() {
        return Integer.parseInt(properties.getProperty("server.max.connections"));
    }

    public long getConnectionTimeoutMs() {
        return Long.parseLong(properties.getProperty("connection.timeout.ms"));
    }

    public boolean isAlarmEnabled() {
        return Boolean.parseBoolean(properties.getProperty("alarm.enabled"));
    }

    // 其他getter方法...
}